<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle">
    <el-autocomplete
      ref="memberAutocompleteRef"
      v-model="queryWord"
      :fetch-suggestions="queryRemote"
      placeholder="输入用户昵称搜索"
      @select="handleSelectMember"
      clearable
    />
    <el-table
      ref="multipleTableRef"
      :data="[...tableData.values()]"
      style="width: 100%; height: 400px"
      :row-key="(row) => row.id"
    >
      <el-table-column type="selection" :reserve-selection="true" />
      <el-table-column property="nickname" label="用户昵称" />
      <el-table-column label="项目角色">
        <template #default="{ row }">
          <el-select v-model="row.projectRoleId" placeholder="请选择">
            <el-option
              v-for="item in roleData"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </template>
      </el-table-column>
    </el-table>
    <template #footer>
      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script lang="ts" setup>
defineOptions({ name: 'MemberForm' })
import * as ProjectApi from '@/api/project'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
const { currentRoute } = useRouter() // 路由对象
const { query: project } = unref(currentRoute)
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型:create - 新增；update - 修改

// 用户搜索框
const memberAutocompleteRef = ref()
// 项目成员列表
const multipleTableRef = ref()

// 查询关键字
const queryWord = ref('')
// 上次查询关键字
const lastQueryWord = ref('')
// 推荐数据
const suggestData = ref<User[]>([])
// 已添加的项目成员列表
const tableData = ref(new Map<number, Member>())
// 项目角色列表
const roleData = ref<Role[]>([])

// 用户
interface User {
  id: number
  nickname: string
}

// 推荐选项
interface Suggestion {
  value: string
  user: User
}

// 项目成员
interface Member {
  id: number
  nickname: string
  projectRoleId: string
}

// 项目角色
interface Role {
  value: string
  label: string
}

const handleScroll = () => {
  const elements = document.querySelectorAll('.el-select__popper')
  elements.forEach((element) => {
    if (element instanceof HTMLElement) {
      element.style.display = 'none'
    }
  })
}

// 添加滚动事件监听器
const addScrollListener = () => {
  const scrollContainer = multipleTableRef.value.$el.querySelector('.el-scrollbar__wrap')
  if (scrollContainer) {
    scrollContainer.addEventListener('scroll', handleScroll)
  }
}

// 移除滚动事件监听器
const removeScrollListener = () => {
  const scrollContainer = multipleTableRef.value?.$el.querySelector('.el-scrollbar__wrap')
  if (scrollContainer) {
    scrollContainer.removeEventListener('scroll', handleScroll)
  }
}

onBeforeUnmount(() => {
  nextTick(() => {
    removeScrollListener()
  })
})

// 打开弹窗
const open = async (type: string) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  reset()
  await getProjectRoleList()
  nextTick(() => {
    addScrollListener()
  })
}

// 重置
const reset = () => {
  queryWord.value = ''
  tableData.value.clear()
}

// 获取项目角色
const getProjectRoleList = async () => {
  try {
    let data = getIntDictOptions(DICT_TYPE.PROJECT_ROLE)
    data = data.filter((d) => {
      if (project.defaulted == '1') {
        return d.value != 'admin'
      } else {
        return true
      }
    })
    roleData.value = JSON.parse(JSON.stringify(data))
  } finally {
  }
}

// 提供 open 方法，用于打开弹窗
defineExpose({ open })

// 提交表单
const emit = defineEmits(['success'])

// 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  if (!multipleTableRef) return
  const selectionRows = multipleTableRef.value.getSelectionRows()
  if (selectionRows.length === 0) {
    if (tableData.value.size != 0) {
      // 未选择用户，直接关闭弹窗
      message.warning('请选择用户')
      return
    }
    // 未添加用户，直接关闭弹窗
    dialogVisible.value = false
    return
  }
  // 判断是否选择了项目角色
  const isNotSelectRole = selectionRows.some((item: Member) => !item.projectRoleId)
  if (isNotSelectRole) {
    message.warning('请选择项目角色')
    return
  }
  // 提交请求
  formLoading.value = true
  try {
    const data = selectionRows.map((item: Member) => {
      return {
        projectId: project.projectId,
        projectRoleId: item.projectRoleId || 'occupant',
        memberId: item.id
      }
    })
    await ProjectApi.createProjectMember(data)
    message.success(t('common.createSuccess'))
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

// 远程查询
const queryRemote = (keyword: string, cb: (arg: Suggestion[]) => void) => {
  if (suggestData.value.length != 0 && keyword === lastQueryWord.value) {
    // 关键字未发生变化
    cb(convertToSuggestList(suggestData.value))
    return
  }
  // 关键字发生变化，重新请求数据
  lastQueryWord.value = keyword
  ProjectApi.getProjectMember({ projectId: project.projectId, nickname: keyword }).then(
    (data: User[]) => {
      suggestData.value = data
      cb(convertToSuggestList(data))
    }
  )
}

// 将数据转换为下拉框的数据格式
const convertToSuggestList = (data: User[]) =>
  data.map((item: User): Suggestion => ({ value: item.nickname, user: item }))

const handleSelectMember = (data: Suggestion) => {
  const user = data.user
  const item: Member = {
    id: user.id,
    nickname: user.nickname,
    projectRoleId: ''
  }
  // 向列表中增加选中的数据
  tableData.value.set(user.id, item)
  multipleTableRef.value.toggleRowSelection(item, true)
  // 关闭下拉框
  memberAutocompleteRef.value.blur()
}
</script>
